@use "sass:math" as math;

/**
 * App custom mixins for SCSS
 * ----------------------------------------------------------------------------
 * Place here our custom mixins.
 */

// Mixes a color with black to create its shade.
// Default to bootstrap level 6.
// --------------------------------------------------------------------------------------------
@function get-color-shade-percent($color, $percent: 48%) {
    @return mix(#000, $color, $percent);
}

// Mixes a color with white to create its tint.
// Default to bootstrap level -10.
// --------------------------------------------------------------------------------------------
@function get-color-tint-percent($color, $percent: 80%) {
    @return mix(#fff, $color, $percent);
}

// Ionic Colors
// --------------------------------------------------
// Generates the color classes and variables based on the
// colors map

@mixin generate-color($color-name, $colors, $theme) {
    $color-themes: map-get($colors, $color-name);
    $base: map-get($color-themes, $theme);

    @if $theme == 'dark' {
        $base: mix(map-get($color-themes, 'light'), white, 80%) !default;
    }

    @include generate-color-variants($color-name, $base);
}

@mixin generate-color-variants($color-name, $base) {
    $contrast: get_contrast_color($base);
    $shade: get-color-shade-percent($base);
    $tint: get-color-tint-percent($base);

    --#{$color-name}: #{$base};
    --#{$color-name}-shade: #{$shade};
    --#{$color-name}-tint: #{$tint};
    --#{$color-name}-contrast: #{$contrast};

    // Internal ionic use only.
    --ion-color-#{$color-name}: var(--#{$color-name});
    --ion-color-#{$color-name}-base: var(--ion-color-#{$color-name});
    --ion-color-#{$color-name}-rgb: #{color-to-rgb-list($base)};
    --ion-color-#{$color-name}-contrast: #{$contrast};
    --ion-color-#{$color-name}-contrast-rgb: #{color-to-rgb-list($contrast)};
    --ion-color-#{$color-name}-shade: #{$shade};
    --ion-color-#{$color-name}-tint: #{$tint};

    .ion-color-#{$color-name} {
        --ion-color: var(--ion-color-#{$color-name});
        --ion-color-base: var(--ion-color-#{$color-name}-base);
        --ion-color-rgb: var(--ion-color-#{$color-name}-rgb);
        --ion-color-contrast: var(--ion-color-#{$color-name}-contrast);
        --ion-color-contrast-rgb: var(--ion-color-#{$color-name}-contrast-rgb);
        --ion-color-shade: var(--ion-color-#{$color-name}-shade);
        --ion-color-tint: var(--ion-color-#{$color-name}-tint);
    }
}

@mixin core-focus-over() {
    &:focus-visible {
        @include core-focus-over-internal();
    }

    @supports not selector(:focus-visible) {
        @at-root:focus {
            @include core-focus-over-internal();
        }
    }
}

@mixin core-focus-outline() {
    &:focus-visible {
        @include core-focus-outline-internal();
    }
    @supports not selector(:focus-visible) {
        @at-root:focus {
            @include core-focus-outline-internal();
        }
    }
}

@mixin core-focus-inset-outline() {
    &:focus-visible {
        @include core-focus-inset-outline-internal();
    }
    @supports not selector(:focus-visible) {
        @at-root:focus {
            @include core-focus-inset-outline-internal();
        }
    }
}

@mixin core-focus-background() {
    &:focus-visible {
        @include core-focus-background-internal();
    }
    @supports not selector(:focus-visible) {
        @at-root:focus {
            @include core-focus-background-internal();
        }
    }
}


@mixin core-focus-over-internal() {
    outline: none;
    position: relative;

    &::after {
        @include position(0px, 0px, 0px, 0px);
        position: absolute;
        content: "";
        z-index: 1;
        pointer-events: none;
        user-select: none;
        @include core-focus-background-internal();
    }
}

@mixin core-focus-outline-internal() {
    outline: var(--a11y-shadow-focus-outline);
    // Use primary for text input controls.
    &:is(
        input:not([type]),
        input[type^=date],
        input[type=email],
        input[type=month],
        input[type=number],
        input[type=password],
        input[type=search],
        input[type=tel],
        input[type=text],
        input[type=time],
        input[type=url],
        input[type=week]
    ) {
        outline-color: var(--primary);
    }
}

@mixin core-focus-inset-outline-internal() {
    @include core-focus-outline-internal();
    outline-offset: calc(var(--a11y-shadow-focus-borderWidth) * -1);
}

@mixin core-focus-background-internal() {
    --background-focused: var(--background-focused, var(--a11y-background-focus-background));
    --background-focused-opacity: var(--a11y-background-focus-opacity);
    --background: var(--a11y-background-focus-background-rgb);
    background: var(--background);
    outline: none;
}

@mixin core-transition($properties: all, $duration: 500ms, $timing-function: ease-in-out) {
    $transitions: ();
    @each $property in $properties {
      $transitions: append($transitions, $property $duration $timing-function, comma);
    }

    -webkit-transition: $transitions;
    transition: $transitions;
}

@mixin sr-only() {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}

@mixin ellipsis($lines: 1) {
    @if ($lines == 1) {
        white-space: nowrap;
        overflow: hidden;
        text-overflow: ellipsis;
    } @else {
        // Only supported on Android 124+, iOs 11+. https://caniuse.com/css-line-clamp
        @supports (-webkit-line-clamp: 2) {
            -webkit-line-clamp: $lines;
            -webkit-box-orient: vertical;
            display: -webkit-box;
            overflow: hidden;
            text-overflow: ellipsis;
            white-space: normal;
        }
    }
}

@mixin pointer-events-on-buttons() {
    a,
    ion-button,
    button,
    audio,
    video,
    select,
    input,
    iframe,
    [role="button"] {
        pointer-events: visible;
    }
}

/**
 * Same as item-push-svg-url but admits flip-rtl
 */
@mixin push-arrow-color($fill: 626262, $flip-rtl: false) {
    $item-detail-push-svg: "<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 20'><path d='M2,20l-2-2l8-8L0,2l2-2l10,10L2,20z' fill='#{$fill}'/></svg>";

    @include svg-background-image($item-detail-push-svg, $flip-rtl);
}

@mixin border-start($px, $type: null, $color: null) {
    @include property-horizontal(border, $px $type $color, null);
}

@mixin border-end($px, $type: null, $color: null) {
    @include property-horizontal(border, null, $px $type $color);
}

@mixin safe-area-border-start($px, $type, $color) {
    $safe-area-position: calc(var(--ion-safe-area-left) + #{$px});

    @include border-start($safe-area-position, $type, $color);
}

@mixin safe-area-border-end($px, $type, $color) {
    $safe-area-position: calc(var(--ion-safe-area-right) + #{$px});

    @include border-end($safe-area-position, $type, $color);
}

@mixin safe-area-margin-horizontal($start, $end: $start) {
    $safe-area-end: null;
    $safe-area-start: null;

    @if ($end) {
        $safe-area-end: calc(var(--ion-safe-area-right) + #{$end});
    }
    @if ($start) {
        $safe-area-start: calc(var(--ion-safe-area-left) + #{$start});
    }

    @include margin-horizontal($safe-area-start, $safe-area-end);
}

@mixin safe-area-margin-start($start, $end) {
    $safe-area-start: calc(var(--ion-safe-area-left) + #{$start});

    @include margin-horizontal($safe-area-start, $end);
}

@mixin safe-area-margin-end($start, $end) {
    $safe-area-end: calc(var(--ion-safe-area-right) + #{$end});

    @include margin-horizontal($start, $safe-area-end);
}

@mixin safe-area-padding-horizontal($start, $end: $start) {
    $safe-area-end: null;
    $safe-area-start: null;

    @if ($end) {
        $safe-area-end: calc(var(--ion-safe-area-right) + #{$end});
    }
    @if ($start) {
        $safe-area-start: calc(var(--ion-safe-area-left) + #{$start});
    }

    @include padding-horizontal($safe-area-start, $safe-area-end);
}

@mixin safe-area-padding-start($start, $end) {
    $safe-area-start: calc(var(--ion-safe-area-left) + #{$start});

    @include padding-horizontal($safe-area-start, $end);
}

@mixin safe-area-padding-end($start, $end) {
    $safe-area-end: calc(var(--ion-safe-area-right) + #{$end});

    @include padding-horizontal($start, $safe-area-end);
}

@mixin safe-area-position($top: null, $end: null, $bottom: null, $start: null) {
    $safe-area-start: calc(var(--ion-safe-area-left) + #{$start});
    $safe-area-end: calc(var(--ion-safe-area-right) + #{$end});

    @include position($top, $safe-area-end, $bottom, $safe-area-start);
}

@mixin core-headings() {
    h1 {
        font: var(--mdl-typography-heading1-font);
    }
    h2, .item-heading {
        font: var(--mdl-typography-heading2-font);
    }
    h3 {
        font: var(--mdl-typography-heading3-font);
    }
    h4 {
        font: var(--mdl-typography-heading4-font);
    }
    h5 {
        font: var(--mdl-typography-heading5-font);
    }
    h6 {
        font: var(--mdl-typography-heading6-font);
    }
}

@mixin darkmode() {
    $root: #{&};

    @at-root #{add-root-selector($root, ":root.dark")} {
        @content;
    }
}

@mixin horizontal_scroll_item($width, $min-width, $max-width) {
    flex: 0 0 $width;
    min-width: $min-width;
    max-width: $max-width;
    align-self: stretch;
    display: block;

    ion-card {
        --vertical-spacing: 10px;
        --horizontal-spacing: 10px;

        width: calc(100% - var(--horizontal-spacing) - var(--horizontal-spacing));
        height: calc(100% - var(--vertical-spacing) - var(--vertical-spacing));
        margin: var(--vertical-spacing) var(--horizontal-spacing);

        @media (max-width: 360px) {
            --horizontal-spacing: 6px;
        }
    }
}

// Color mixins.
@function get_brightness($color) {
    @return math.div(red($color) + green($color) + blue($color), 3);
}

// Get the better color contrast using WCAG algorythm.
@function get_contrast_color($color) {
    $lumiance: luminance($color);

    // White lumiance is 1.
    $whiteContrast: math.div($lumiance + 0.05, 1 + 0.05);
    // White lumiance is 0.
    $blackContrast: math.div(0.05, $lumiance + 0.05);

    @return if($whiteContrast < $blackContrast, white, black);
}

// Color contrast using yiq aproximation with 150 threshold.
@function get_contrast_color_yiq($color, $dark: black, $light: white) {
    $r: red($color);
    $g: green($color);
    $b: blue($color);

    $yiq: math.div(($r * 299) + ($g * 587) + ($b * 114), 1000);

    @return if($yiq >= 128, $dark, $light);
}

// WCAG contrast algorithm
@function check-contrast($foreground, $background) {
    $foregroundLumiance: luminance($foreground);
    $backgroundLuminance: luminance($background);

    @if ($backgroundLuminance < $foregroundLumiance) {
        @return math.div($backgroundLuminance + 0.05, $foregroundLumiance + 0.05);
    } @else {
        @return math.div($foregroundLumiance + 0.05, $backgroundLuminance + 0.05);
    }
}

@function luminance($color) {
    $r: red($color);
    $g: green($color);
    $b: blue($color);

    $r: component-luminance($r);
    $g: component-luminance($g);
    $b: component-luminance($b);

    @return $r * 0.2126 + $g * 0.7152 + $b * 0.0722;
}

@function component-luminance($value) {
    $value: math.div($value, 255);

    @if ($value <= 0.03928) {
        @return math.div($value, 12.92);
    } @else {
        @return math.pow(math.div($value + 0.055, 1.055), 2.4);
    }
}
